package com.fruit.web.vo.goods;

import java.util.ArrayList;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.hibernate.SessionFactory;

import com.fruit.hibernate.dao.support.Page;
import com.fruit.service.IBrandService;
import com.fruit.service.IGoodsService;
import com.fruit.service.IFruitCategoryService;
import com.fruit.utils.DESPlusUtil;
import com.fruit.utils.MessageFactory;
import com.fruit.utils.PageExistUtil;
import com.fruit.utils.SpringFacesUtil;
import com.fruit.web.bo.impl.Brand;
import com.fruit.web.bo.impl.Goods;
import com.fruit.web.bo.impl.FruitCategory;
import com.fruit.web.common.bean.DoubleRange;
import com.fruit.web.constant.EjdConstants;
import com.fruit.web.constant.SpringBeanConstants;

public class ListGoodsPageBean {//适合按大类,小类 ,品牌,但小类,品牌可以为空的GOODS的查询,如果有其他属性,需要在此基础上重新定义
	private String defaultHql;
	private boolean propertyOpenFlag = true;//this is for open or close the property windows
	private boolean searchParamChangeFlag = false;
	private String primaryCategoryCode;
	private String[] brandCodes = null;
	private SelectItem[] brandCodeItems = null;
	private String[] secondCategories = null;
	private SelectItem[] secondCategoryItems = null;
	private Page<Goods,Long> page = new Page<Goods,Long>();
	private SelectItem[] pageItems = null;
	private Integer pageSize =30;
	private Integer pageNo = 1;
	
	
	// this is show in page 
	private List<Goods> promotionGoods = new ArrayList<Goods>();
	private List<Goods> hotGoods = new ArrayList<Goods>();
	private List<Goods> recommendGoods = new ArrayList<Goods>();
	//end
	
	private SelectItem[] pageSizeItems = {
		new SelectItem(new Long(30),"30"),
		new SelectItem(new Long(60),"60"),
		new SelectItem(new Long(100),"100"),
	};
	private String priceBetween = "N";
	private static SelectItem[] priceBetweenItems = {
		new SelectItem("N","显示所有"),
		new SelectItem("A","200以下"),
		new SelectItem("B","200-300"),
		new SelectItem("C","300-400"),
		new SelectItem("D","400-500"),
		new SelectItem("E","500以上"),
	};
	private DoubleRange priceRange = new DoubleRange();
	private List<DoubleRange> priceRangeList = new ArrayList<DoubleRange>();
	private String sortStyle = "N";//default is viewint asc
	private String sessionId;
	
	private static SelectItem[] sortStyleItems = {
		new SelectItem("NO","默认排序"),
		new SelectItem("PA","价格从低到高"),
		new SelectItem("PD","价格从高到低"),
		new SelectItem("TA","上市由早到晚"),
		new SelectItem("TD","上市由晚到早"),
	};
	
	public String getDefaultHql() {
		return defaultHql;
	}

	public void setDefaultHql(String defaultHql) {
		this.defaultHql = defaultHql;
	}
	// this if for search data
	private String hql;
	private Object[] values;// search parameter
	// end
	
	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}

	public Integer getPageNo() {
		return pageNo;
	}

	public void setPageNo(Integer pageNo) {
		this.pageNo = pageNo;
	}

	public SelectItem[] getPageSizeItems() {
		return pageSizeItems;
	}

	public void setPageSizeItems(SelectItem[] pageSizeItems) {
		this.pageSizeItems = pageSizeItems;
	}
	public boolean isPropertyOpenFlag() {
		return propertyOpenFlag;
	}


	public void setPropertyOpenFlag(boolean propertyOpenFlag) {
		this.propertyOpenFlag = propertyOpenFlag;
	}


	public boolean isSearchParamChangeFlag() {
		return searchParamChangeFlag;
	}

	public void setSearchParamChangeFlag(boolean searchParamChangeFlag) {
		this.searchParamChangeFlag = searchParamChangeFlag;
	}
	
	public String getPrimaryCategoryCode() {
		return primaryCategoryCode;
	}

	public void setPrimaryCategoryCode(String primaryCategoryCode) {
		this.primaryCategoryCode = primaryCategoryCode;
	}

	public String[] getBrandCodes() {
		return brandCodes;
	}


	public void setBrandCodes(String[] brandCodes) {
		this.brandCodes = brandCodes;
	}

	public SelectItem[] getBrandCodeItems() {
		return brandCodeItems;
	}

	public void setBrandCodeItems(SelectItem[] brandCodeItems) {
		this.brandCodeItems = brandCodeItems;
	}

	public Integer getBrandCodeItemsLength(){
		return this.getBrandCodeItems().length;
	}

	public String[] getSecondCategories() {
		return secondCategories;
	}


	public void setSecondCategories(String[] secondCategories) {
		this.secondCategories = secondCategories;
	}



	public SelectItem[] getSecondCategoryItems() {
		return secondCategoryItems;
	}


	public void setSecondCategoryItems(SelectItem[] secondCategoryItems) {
		this.secondCategoryItems = secondCategoryItems;
	}

	public Integer getSecondCategoryItemsLength(){
		return this.getSecondCategoryItems().length;
	}

	public Page<Goods, Long> getPage() {
		return page;
	}


	public void setPage(Page<Goods, Long> page) {
		this.page = page;
	}


	public SelectItem[] getPageItems() {
		return pageItems;
	}

	public void setPageItems(SelectItem[] pageItems) {
		this.pageItems = pageItems;
	}

	public String getHql() {
		return hql;
	}

	public void setHql(String hql) {
		this.hql = hql;
	}

	public Object[] getValues() {
		return values;
	}

	public void setValues(Object[] values) {
		this.values = values;
	}

	public String getPriceBetween() {
		return priceBetween;
	}

	public void setPriceBetween(String priceBetween) {
		this.priceBetween = priceBetween;
	}

	public SelectItem[] getPriceBetweenItems() {
		return priceBetweenItems;
	}

	public void setPriceBetweenItems(SelectItem[] priceBetweenItems) {
		this.priceBetweenItems = priceBetweenItems;
	}

	public DoubleRange getPriceRange() {
		return priceRange;
	}

	public void setPriceRange(DoubleRange priceRange) {
		this.priceRange = priceRange;
	}

	public List<DoubleRange> getPriceRangeList() {
		return priceRangeList;
	}

	public void setPriceRangeList(List<DoubleRange> priceRangeList) {
		this.priceRangeList = priceRangeList;
	}

	public String getSortStyle() {
		return sortStyle;
	}

	public void setSortStyle(String sortStyle) {
		this.sortStyle = sortStyle;
	}

	public SelectItem[] getSortStyleItems() {
		return sortStyleItems;
	}

	public void setSortStyleItems(SelectItem[] sortStyleItems) {
		this.sortStyleItems = sortStyleItems;
	}

	
	public String getSessionId() {
		return sessionId;
	}

	public void setSessionId(String sessionId) {
		this.sessionId = sessionId;
	}

	
	public List<Goods> getPromotionGoods() {
		return promotionGoods;
	}

	public void setPromotionGoods(List<Goods> promotionGoods) {
		this.promotionGoods = promotionGoods;
	}

	public List<Goods> getHotGoods() {
		return hotGoods;
	}

	public void setHotGoods(List<Goods> hotGoods) {
		this.hotGoods = hotGoods;
	}

	public List<Goods> getRecommendGoods() {
		return recommendGoods;
	}

	public void setRecommendGoods(List<Goods> recommendGoods) {
		this.recommendGoods = recommendGoods;
	}

	public ListGoodsPageBean(){
		
	}

	public String openPropertyWindows() {
		this.setPropertyOpenFlag(true);
		return null;
	}
	public String closePropertyWindows() {
		this.setPropertyOpenFlag(false);
		return null;
	}
	
	protected Page<Goods,Long> getData(String hql, int pageNo, int pageSize, Object... values) {
		IGoodsService<Goods,Long> goodsService = (IGoodsService<Goods,Long>)SpringFacesUtil.getSpringBean(SpringBeanConstants.GOODS_SERVICE_BEAN_NAME);
		goodsService.setEntityClass(Goods.class);
		goodsService.setPKClass(Long.class);
		Page<Goods,Long> resultPage = goodsService.pagedQuery(hql, pageNo, pageSize,values); 
		return resultPage;
	}
	
	protected void initBrandCodes(){
		// start set brand code items
		IGoodsService<Goods,Long> goodsService = (IGoodsService<Goods,Long>)SpringFacesUtil.getSpringBean(SpringBeanConstants.GOODS_SERVICE_BEAN_NAME);
		goodsService.setEntityClass(Goods.class);
		goodsService.setPKClass(Long.class);
		List<String> params = new ArrayList<String>();
		List<String> values = new ArrayList<String>();
		generatePropertyParamsAndValues(params, values);
		List<String> theBrandCodes = goodsService.getPropertyCodes(EjdConstants.BRAND_CODE,params,values);
		SelectItem[] tempBrandItems = null;
		if (null != theBrandCodes && !(theBrandCodes.isEmpty())) {
			IBrandService<Brand,Long> brandService = (IBrandService<Brand,Long>)SpringFacesUtil.getSpringBean(SpringBeanConstants.BRAND_SERVICE_BEAN_NAME);
			brandService.setEntityClass(Brand.class);
			brandService.setPKClass(Long.class);
			tempBrandItems = new SelectItem[theBrandCodes.size()];
			for (int i=0; i< theBrandCodes.size(); i ++) {
				String brandCode = theBrandCodes.get(i);
				if (null == brandCode || "".equals(brandCode)) {
					continue;
				}
				Brand brand = brandService.findUniqueBy("brandCode", brandCode);
				tempBrandItems[i] = new SelectItem(brand.getBrandCode(),brand.getBrandName());
			}
		} else {
			tempBrandItems = new SelectItem[1];
			tempBrandItems[0] = new SelectItem("","");
		}
		this.setBrandCodeItems(tempBrandItems);
		// end set brand code items
	}
	protected void initSecondCategory(){
		IGoodsService<Goods,Long> goodsService = (IGoodsService<Goods,Long>)SpringFacesUtil.getSpringBean(SpringBeanConstants.GOODS_SERVICE_BEAN_NAME);
		goodsService.setEntityClass(Goods.class);
		goodsService.setPKClass(Long.class);
		// start set secondCategory items
		List<String> params = new ArrayList<String>();
		List<String> values = new ArrayList<String>();
		generatePropertyParamsAndValues(params, values);
		List<String> theSecondCategories = goodsService.getPropertyCodes(EjdConstants.SFIELD1,params,values);
		SelectItem[] tempSecondCategoryItems = null;
		if (null != theSecondCategories && !(theSecondCategories.isEmpty())) {
			IFruitCategoryService<FruitCategory,Long> subCategoryService = (IFruitCategoryService<FruitCategory,Long>)SpringFacesUtil.getSpringBean(SpringBeanConstants.FRUIT_CATEGORY_SERVICE_BEAN_NAME);
			subCategoryService.setEntityClass(FruitCategory.class);
			subCategoryService.setPKClass(Long.class);
			tempSecondCategoryItems = new SelectItem[theSecondCategories.size()];
			for (int i=0; i< theSecondCategories.size(); i ++) {
				String categoryCode = theSecondCategories.get(i);
				if (null == categoryCode || "".equals(categoryCode)) {
					continue;
				}
				FruitCategory subCategory = subCategoryService.findUniqueBy("categoryCode", categoryCode);
				String subCategoryNameN18 = MessageFactory.getMessage(EjdConstants.USER_BUNDLE_NAME,subCategory.getCategoryName(), FacesMessage.SEVERITY_ERROR).getDetail();
				tempSecondCategoryItems[i] = new SelectItem(subCategory.getCategoryCode(),subCategoryNameN18,subCategory.getCategoryCode());
				
			}
		} else {
			tempSecondCategoryItems = new SelectItem[1];
			tempSecondCategoryItems[0] = new SelectItem("","");
		}
		this.setSecondCategoryItems(tempSecondCategoryItems);
		// end set secondCategory items
	}
	protected void initPriceRangeList(){
		List<DoubleRange> tempPriceRange = new ArrayList<DoubleRange>();
		tempPriceRange.add(new DoubleRange(new Double(0),new Double(100),"0-100"));
		tempPriceRange.add(new DoubleRange(new Double(100),new Double(200),"100-200"));
		tempPriceRange.add(new DoubleRange(new Double(200),new Double(399.9),"200-399.9"));
		tempPriceRange.add(new DoubleRange(new Double(400),new Double(599.9),"400-599.9"));
		tempPriceRange.add(new DoubleRange(new Double(600),null,">=600"));
		this.setPriceRangeList(tempPriceRange);
		
	}//默认查询价格列表,可以根据具体情况在子类中重写.

	protected void initConditionItems(){
		/*List<SelectItem> result = constructConditionItems();
		this.setConditionItems(result);*/
	}
	protected void generatePropertyParamsAndValues(List<String> params, List<String> values){
		if (null == params) {
			params = new ArrayList<String>();
		}
		params.clear();
		if (null == values) {
			values = new ArrayList<String>();
		}
		values.clear();
		//start set primaryCategoryCode
		params.add(EjdConstants.PRIMARY_CATEGORY_CODE);
		values.add(this.getPrimaryCategoryCode());
		//end set primaryCategoryCode
		// set brandCode start
		if (null == this.getBrandCodes()) {
			this.setBrandCodes(new String[]{""});
		}
		if (!"".equals(this.getBrandCodes()[0])) {
			params.add(EjdConstants.BRAND_CODE);
			values.add(this.getBrandCodes()[0]);
		}
		// set brandCode end
		// set SecondCategories start
		if (null == this.getSecondCategories()) {
			this.setSecondCategories(new String[]{""});
		}
		if (!"".equals(this.getSecondCategories()[0])) {
			params.add(EjdConstants.SFIELD1);
			values.add(this.getSecondCategories()[0]);
		}
		// set SecondCategories end
		
		
	}
	
	public String goDetailPage(){
		String primaryCategoryCode = (String) SpringFacesUtil.getRequestParameter("primaryCategoryCode");
		String code =(String) SpringFacesUtil.getRequestParameter("code");
		String productId =(String) SpringFacesUtil.getRequestParameter("productId");
		if (PageExistUtil.checkPageExist(code+".xhtml", "/layout/goods/shoes") && PageExistUtil.checkPageExist(code+"Detail.xhtml", "/layout/goods/shoes/sub") ) {
			return code + "?faces-redirect=true&primaryCategoryCode=" + DESPlusUtil.encrypt(primaryCategoryCode) + "&code=" + DESPlusUtil.encrypt(code) + "&productId=" + DESPlusUtil.encrypt(productId);
		} else {
			return "/WEB-INF/" + EjdConstants.NO_PRODUCT_DETAIL_PAGE;
		}
	}
	// this function is generate hql and parameters.
	protected void generateHQL(String defaultHql) {//defaultHql is default hql, values is parameter
		String hql = defaultHql;
		List paraList = new ArrayList();
		
		if (null != this.getPrimaryCategoryCode() && !("".equals(this.getPrimaryCategoryCode()))) {
			hql = hql + " and primaryCategoryCode = '" + this.getPrimaryCategoryCode() + "' ";
		}
		
		if (null != this.getBrandCodes() && this.getBrandCodes().length > 0 && (null != this.getBrandCodes()[0]) && (!("".equals(this.getBrandCodes()[0])))) {
			hql = hql + " and brandCode in (";
			String[] tempBrandCodes = this.getBrandCodes();
			for (int i=0 ; i < tempBrandCodes.length; i++) {
				hql = hql + "?";
				if (i != (tempBrandCodes.length -1)) {
					hql = hql + ",";
				}
				paraList.add(tempBrandCodes[i]);
			}
			hql = hql + ") ";
		}
		if (null != this.getSecondCategories() && this.getSecondCategories().length > 0 && (null != this.getSecondCategories()[0]) && (!("".equals(this.getSecondCategories()[0])))) {
			hql =  hql + " and sfield1 in (";
			String[] tempSecondCategories = this.getSecondCategories();
			for (int i=0 ; i < tempSecondCategories.length; i++) {
				hql = hql + "?";
				if (i != (tempSecondCategories.length -1)) {
					hql = hql + ",";
				}
				paraList.add(tempSecondCategories[i]);
			}
			hql = hql + ") ";
		}
		if (null != this.getPriceBetween() && !("N".equals(this.getPriceBetween()))) {
			if ("A".equals(this.getPriceBetween())) {
				hql = hql + " and retailPrice < 200 " ;
			}
			if ("B".equals(this.getPriceBetween())) {
				hql = hql + " and retailPrice >= 200 and retailPrice < 300 " ;
			}
			if ("C".equals(this.getPriceBetween())) {
				hql = hql + " and retailPrice >=300  and retailPrice < 400 " ;
			}
			if ("D".equals(this.getPriceBetween())) {
				hql = hql + " and retailPrice >=400  and retailPrice < 500 " ;
			}
			if ("E".equals(this.getPriceBetween())) {
				hql = hql + " and retailPrice >= 500 " ;
			}
		}
		if (null != this.getPriceRange() && null != this.getPriceRange().getMin()) {
			hql = hql + " and retailPrice >= " + this.getPriceRange().getMin();
		}
		if (null != this.getPriceRange() && null != this.getPriceRange().getMax()) {
			hql = hql + " and retailPrice <= " + this.getPriceRange().getMax();
		}
		if (null == this.getSortStyle() || "NO".equals(this.getSortStyle())) {
			hql = hql + " order by viewInt asc ";
		} else if ("PA".equals(this.getSortStyle())) {
			hql = hql + " order by retailPrice asc ";
		} else if ("PD".equals(this.getSortStyle())) {
			hql = hql + " order by retailPrice desc ";
		} else if ("TA".equals(this.getSortStyle())) {
			hql = hql + " order by timeToMarket asc ";
		} else if ("TD".equals(this.getSortStyle())) {
			hql = hql + " order by timeToMarket desc ";
		}
		Object[] tempValues = null;
		if (paraList.size() > 0) {
			tempValues = new Object[paraList.size()];
			for (int i = 0; i< tempValues.length;i++) {
				tempValues[i] = paraList.get(i);
			}
		}
		this.setValues(tempValues);
		this.setHql(hql);
	}
	protected void getPageDatas() {
		Page<Goods,Long> resultPage = this.getData(this.getHql(), this.getPageNo(), this.getPageSize(), this.getValues());
		this.setPage(resultPage);
		SelectItem[] tempPageItem = new SelectItem[(int)resultPage.getTotalPageCount()];
		for (int j=0;j<tempPageItem.length;j++) {
			tempPageItem[j]= new SelectItem(new Integer(j+1),String.valueOf(j+1));
		}
		this.setPageItems(tempPageItem);
	}
	public String changePageNo(){
		System.out.println(this.getPageNo());
		this.getPageDatas();
		return null;
	}
	public String selectPageNo() {
		String result = null;
		String pageNo = (String) SpringFacesUtil.getRequestParameter("pageNo");
		if (this.getPageNo().intValue() == Integer.valueOf(pageNo).intValue()) {
			return result;
		}
		this.setPageNo(Integer.valueOf(pageNo).intValue());
		this.getPageDatas();
		return result;
		
	}
	public void pageSizeValueChangeListener(ValueChangeEvent event) {
		Integer newPageSize = (Integer)event.getNewValue();
		this.setPageSize(newPageSize);
		this.setPageNo(1);
		this.getPageDatas();
	}
	public void searchParamChangeListener(ValueChangeEvent event){
		this.setSearchParamChangeFlag(true);
		System.out.println("======="+"true");
	}
	
	// start used for men and women common function
	public String searchDataNoneParamByCustomer() {
		this.setPageNo(1);
		if (!("N".equals(this.getPriceBetween()))) {
			this.setPriceBetween("N");
		}
		if (null != this.getBrandCodes()) {
			this.getBrandCodes()[0] = "";
		}
		if (null != this.getSecondCategories()) {
			this.getSecondCategories()[0] = "";
		}
		this.generateHQL(this.getDefaultHql());
		this.getPageDatas();
		return null;
	}
	public void priceBetweenValueChangeListener(ValueChangeEvent event) {
		String priceBetween = (String)event.getNewValue();
		this.setPageNo(1);
		this.setPriceBetween(priceBetween);
		initConditionItems();
		this.generateHQL(this.getDefaultHql());
		this.getPageDatas();
	}
	public void sortStyleValueChangeListener(ValueChangeEvent event) {
		String sortStyle = (String)event.getNewValue();
		this.setPageNo(1);
		this.setSortStyle(sortStyle);
		this.generateHQL(this.getDefaultHql());
		this.getPageDatas();
	}
	
	public String selectBrandCode(){
		String brandCode = (String) SpringFacesUtil.getRequestParameter("brandCode");
		if (null != this.getBrandCodes()) {
			if (this.getBrandCodes().length > 0 && (this.getBrandCodes()[0].equals(brandCode))) {
				this.getBrandCodes()[0] = "";
			} else {
				this.getBrandCodes()[0] = brandCode;
			}
		} else {
			String[] tempBrandCodes = new String[1];
			tempBrandCodes[0] = brandCode;
			this.setBrandCodes(tempBrandCodes);
		}
		initConditionItems();
		this.generateHQL(this.getDefaultHql());
		this.getPageDatas();
		return null;
	}
	public String unSelectBrandCode(){
		if (null != this.getBrandCodes()) {
			this.setBrandCodes(new String[]{""});
		} else {
			this.getBrandCodes()[0] = "";
		}
		this.generateHQL(this.getDefaultHql());
		this.getPageDatas();
		return null;
	}
	public String selectSecondCategory(){
		String secondCategory = (String) SpringFacesUtil.getRequestParameter("secondCategory");
		if (null != this.getSecondCategories()) {
			if (this.getSecondCategories().length > 0 && (this.getSecondCategories()[0].equals(secondCategory))) {
				this.getSecondCategories()[0] = "";
			} else {
				this.getSecondCategories()[0] = secondCategory;
			}
		} else {
			String[] tempSecondCategory = new String[1];
			tempSecondCategory[0] = secondCategory;
			this.setSecondCategories(tempSecondCategory);
		}
		initConditionItems();
		this.generateHQL(this.getDefaultHql());
		this.getPageDatas();
		return null;
	}
	public String unSelectSecondCategory(){
		if (null != this.getSecondCategories()) {
			this.setSecondCategories(new String[]{""});
		} else {
			this.getSecondCategories()[0] = "";
		}
		this.generateHQL(this.getDefaultHql());
		this.getPageDatas();
		return null;
	}
}
